﻿using System.Collections.Generic; // Add this line
using System.Net.Sockets;
using System.Text;
using Newtonsoft.Json;
using System;
using System.IO;
using System.IO.Pipes;
using JetBrains.Annotations;
using UnityEngine;
using Newtonsoft.Json.Linq;

public partial class CyberU
{
    #region Network

    public static string DefaultIp = "127.0.0.1";
    public static int DefaultPort = 7001;

    public static string? SendCode2CyberuWithTcp(string code)
    {
        Dictionary<string, object> dictionary = new Dictionary<string, object>();
        dictionary.Add("command", code);
        dictionary.Add("content", "");
        return Send2Node(dictionary, DefaultIp, DefaultPort);
    }

    public static string Send2Node(Dictionary<string, object> dictionary, string ip, int port)
    {
        try
        {
            string message = JsonConvert.SerializeObject(dictionary);
            TcpClient client = new TcpClient();
            client.Connect(ip, port);
            NetworkStream stream = client.GetStream();
            byte[] data = Encoding.UTF8.GetBytes(message);
            stream.Write(data, 0, data.Length);
            stream.Close();
            client.Close();
            System.Console.WriteLine($"字典字符串已发送到 {ip}:{port}，内容为: {message}");
            return "";
        }
        catch (System.Exception e)
        {
            System.Console.Error.WriteLine($"发送数据到 {ip}:{port} 时出错: " + e.Message);
        }

        return "";
    }

    #endregion

    #region PipeLine

    // private static string pipeName = @"\\.\pipe\HISHIGHNESS";
    private static string pipeName = @"HISHIGHNESS";
    private static NamedPipeClientStream? pipeClient = null;
    public static string NULL_SYMBOL = "null";

    public static void CreatePipeLine(int timeout = 20000)
    {
        if (pipeClient == null || !pipeClient.IsConnected)
        {
            pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut);
            try
            {
                pipeClient.Connect(timeout);
                // Delog("管道连接成功！");
            }
            catch (TimeoutException)
            {
                // DelogError("连接管道超时，请检查服务端是否运行");
                pipeClient = null;
                throw;
            }
        }
    }

    public static void ClosePipeLine()
    {
        if (pipeClient != null)
        {
            pipeClient.Close();
            pipeClient = null;
            Console.WriteLine("Pipe closed.");
        }
    }

    public static object? Send(string codeStr, int maxRetries = 3)
    {
        return SendCodeWithPipeline(codeStr, maxRetries);
    }

    public static object? SendCode(string codeStr, int maxRetries = 3)
    {
        return SendCodeWithPipeline(codeStr, maxRetries);
    }

    public static object? SendCode2Cyberu(string codeStr, int maxRetries = 3)
    {
        return SendCodeWithPipeline(codeStr, maxRetries);
    }
    public static object? SendCodeWithPipeline(string codeStr, int maxRetries = 3)
    {
        // print("start SendCodeWithPipeline");
        
        if (pipeClient == null || !pipeClient.IsConnected)
        {
            CreatePipeLine(); // 如果未连接，则尝试创建管道
        }

        int retryCount = 0;
        while (retryCount < maxRetries)
        {
            try
            {
                byte[] buffer = Encoding.UTF8.GetBytes(codeStr);
                // Delog("sending ...");
                pipeClient?.Write(buffer, 0, buffer.Length);
                
                
                byte[] responseBuffer = new byte[1024 * 50];
                int bytesRead = pipeClient?.Read(responseBuffer, 0, responseBuffer.Length) ?? 0;
                string responseJson = Encoding.UTF8.GetString(responseBuffer, 0, bytesRead);
                // Delog($"接收到的响应字符串: {responseJson}");
                if (string.IsNullOrEmpty(responseJson) || responseJson == NULL_SYMBOL)
                {
                    // Delog("pipeline return is empty str.");
                    return null;
                }
                var jsonObj = JsonConvert.DeserializeObject<Dictionary<string, object>>(responseJson);
                if (jsonObj != null && jsonObj.TryGetValue("result", out object? resultValue))
                {
                    // Print(resultValue);
                    if (resultValue is string strResult)
                    {
                        // Print("perceived as strResult");
                        return strResult;
                    }
                    else if (resultValue is JObject jObjectResult)
                    {
                        // Print("perceived as jObject");
                        return jObjectResult;
                    }
                    else if (resultValue is JArray jArrayResult)
                    {
                        // Print("perceived as jArray");
                        GetType(jArrayResult);
                        // print(jArrayResult, "return");
                        return jArrayResult;
                    }
                    Delog($"no processing. the return is {resultValue}");
                    return resultValue;
                }
                // Print("Doing again.");
                return null; // JSON 中没有 "result" 字段
            }
            catch (IOException ex) when (ex.Message.Contains("Pipe is broken") || ex is TimeoutException)
            {
                retryCount++;
                WarnLog($"管道连接中断，尝试重新连接 (重试 {retryCount}/{maxRetries})");

                // 关闭现有连接并尝试重新连接
                ClosePipeLine();
                CreatePipeLine();

                if (retryCount >= maxRetries)
                {
                    DelogError($"管道通信失败，已达到最大重试次数: {ex.Message}");
                    return null;
                }
            }
            catch (Exception ex)
            {
                DelogError($"管道通信发生未知错误: {ex.Message}");
                return null;
            }
            Delog("should not be here.");
        }
        return null;
    }
    #endregion
}